//
//  FQGradientProgressView.m
//  FQChargingProgressView
//
//  Created by issuser on 2021/11/11.
//

#import "FQGradientProgressView.h"

#define rgba(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]

@interface RGBValue : NSObject

@property (assign, nonatomic) CGFloat r;
@property (assign, nonatomic) CGFloat g;
@property (assign, nonatomic) CGFloat b;

@end

@implementation RGBValue

@end


@interface FQGradientProgressView ()

@property (strong, nonatomic) UIImageView * conentImgView;

@property (strong, nonatomic) NSMutableArray * dotViews;

@end


@implementation FQGradientProgressView

-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self creatUI];
    }
    return self;
}

-(void)creatUI{
    self.conentImgView.frame = self.bounds;
    [self addSubview:self.conentImgView];
}

-(void)setConfig:(FQGradientProgressConfig *)config
{
    _config = config;
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, config.radius * 2.0 + config.rWidth, config.radius * 2.0 + config.rWidth);
    self.conentImgView.frame = CGRectMake(0, 0, config.radius * 2.0 + config.rWidth, config.radius * 2.0 + config.rWidth);
    UIImage * img = [self createGradientRingImage:config.radius width:config.rWidth gradient:config.gradients angleValues:config.angleValues];
    self.conentImgView.image = img;
    
}

-(UIImageView *)conentImgView
{
    if (!_conentImgView) {
        _conentImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 320)];
        _conentImgView.backgroundColor = UIColor.blackColor;
        
    }
    return _conentImgView;
}

/// 此函数为了防止数据异常.例如[360.0.0.0]界面效果不美观的优化.返回优化后的数据[144.72.72.72]
/// @param values 原始数据
-(NSArray *)changeValuesWithArr:(NSArray *)values{
    
    //平均分到每个数据为
    NSMutableArray * angleValues = [NSMutableArray arrayWithArray:values];
    
    NSNumber *sum = [angleValues valueForKeyPath:@"@sum.self"];
    CGFloat itemBaseValue = sum.floatValue * 0.8 / values.count;
    
    NSMutableArray * tempArr = [NSMutableArray array];
    NSInteger count = 0;
    for (NSNumber * itemValue in angleValues) {
        [tempArr addObject:@(itemValue.floatValue * 0.2 + itemBaseValue)];
        count ++;
    }
    angleValues = tempArr;
    
    return angleValues.copy;
}

/// 创建渐变图层
/// @param radius 圆环半径
/// @param width 圆环的宽
/// @param gradients 渐变颜色值数组.
/// @param angleValues 渐变弧度值数组.
-(UIImage *)createGradientRingImage:(CGFloat)radius width:(CGFloat)width gradient:(NSArray <UIColor *>*)gradients angleValues:(NSArray *)angleValues{
    
    if (angleValues.count == 0 || gradients.count == 0) {
        return UIImage.new;
    }
    //处理数据.控制在180以内.优化展示效果
    angleValues = [self changeValuesWithArr:angleValues];
    
    NSMutableArray * mpiArr = [NSMutableArray array];
    NSNumber *sum = [angleValues valueForKeyPath:@"@sum.self"];

    CGFloat sumValue = sum.floatValue;
    CGFloat tempValue = 0.0;
    for (NSNumber * itemValue in angleValues) {
        CGFloat item = [itemValue floatValue] / sumValue;
        tempValue += item * 2.0 * M_PI;
        [mpiArr addObject:@(tempValue)];
    }
    
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(2*radius + width, 2*radius + width),NO,[UIScreen mainScreen].scale);  //开始画线
    CGFloat margin = 0;//0.09 * M_PI;
    UIColor * bgColor = UIColor.clearColor;
    NSInteger dakeCount = 0;
    CGFloat tempAngle = 0.0;
    for (NSNumber * mpiValue in mpiArr) {
        CGFloat currentAngle = [mpiValue floatValue];
        if (gradients.count > dakeCount) {
            UIColor * mpiColor = gradients[dakeCount];
            CGFloat beginAngle = tempAngle;
            CGFloat endAngle = (currentAngle - margin);
            
            CGFloat beginA = 180 * beginAngle / M_PI;
            CGFloat endA = 180 * endAngle / M_PI;
            
            //优化展示效果.
            CGFloat offsetAngle = endA - beginA;
            NSMutableArray * gradientMuArr = [NSMutableArray array];
            //每30弧度算一个刻度
            int colorCount = ceilf(offsetAngle / 30.0);
            for (int i = 0; i < colorCount - 1; i ++) {
                [gradientMuArr addObject:mpiColor];
            }
            if (gradientMuArr.count == 0) {
                [gradientMuArr addObject:mpiColor];
            }
            [gradientMuArr addObject:bgColor];
            
            NSLog(@"大可------------------------------->%f",endA - beginA);
//            if (dakeCount == 2) {
//                UIImage *upperImage = [self createGradientSemiCircleImageRadius:radius width:width gradient:gradientMuArr startAngle:beginAngle endAngle:endAngle upper:0];
//                [upperImage drawInRect:CGRectMake(width * 0.5, width * 0.5, radius*2, radius * 2)];
//            }
            UIImage *upperImage = [self createGradientSemiCircleImageRadius:radius width:width gradient:gradientMuArr startAngle:tempAngle endAngle:currentAngle - margin upper:0];
            [upperImage drawInRect:CGRectMake(width * 0.5, width * 0.5, radius*2, radius * 2)];
        }
        tempAngle = currentAngle;
        dakeCount ++;
    }
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}


/// 创建一个渐变的弧度
/// @param radius 半径
/// @param width 弧度的宽度
/// @param gradient 渐变数组
/// @param startAngle 开始弧度 0 - 2 * M_PI
/// @param endAngle 结束弧度 0 - 2 * M_PI
/// @param upper 0
-(UIImage *)createGradientSemiCircleImageRadius:(CGFloat)radius width:(CGFloat)width gradient:(NSArray <UIColor *>*)gradient startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle upper:(NSInteger)upper{
    //开始弧度
    CGFloat beginA = 180 * startAngle / M_PI;
    CGFloat endA = 180 * endAngle / M_PI;
    
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(2*radius + width, radius * 2 + width),NO,[UIScreen mainScreen].scale);  //开始画线
    //获取上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineJoin(context, kCGLineJoinRound);

    CGContextSaveGState(context);
    CGContextSetLineWidth(context, width);
    //弧度缩进一点.因为有圆角和半径宽度
    CGFloat offetMargin = M_PI * 10 / 180;
    CGContextAddArc(context, radius + width * 0.5, radius + width * 0.5, radius, startAngle + offetMargin , endAngle - offetMargin, 0);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSMutableArray *colorArray = [NSMutableArray array];
    for (UIColor *color in gradient) {
        [colorArray addObject:(id)color.CGColor];
    }
    CGGradientRef gradientRef = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colorArray, NULL);
#warning 待优化 -- 设置过效果不佳
    
//    CGFloat components[gradient.count * 4];
//    NSInteger count = 0;
//    for (UIColor *color in gradient) {
//        RGBValue * rgb = [self readRGBForUIColor:color];
//        components[count] = rgb.r / 255.0;
//        components[count+1] = rgb.g / 255.0;
//        components[count+2] = rgb.b / 255.0;
//        NSInteger hasShow = (count + 3 == (gradient.count * 4 - 1)) ? 0 : 1;
//        components[count+3] = hasShow;
//        NSLog(@"大可----------------------->count:%zd-->%zd-->%zd",count + 3,gradient.count - 1,hasShow);
//        count += 4;
//    }
//    //保障尾部有一定的效果.
//    CGFloat progress =  0.5;
//    CGFloat endProgress = progress + (1 - progress) * 0.5;
//
//    CGFloat sumOffset = fabs(beginA - endA);
//    if (sumOffset != 0 && sumOffset > 90.0) {
//        progress = (sumOffset - 30) / sumOffset;
//        endProgress = MIN(progress + ( 1 - progress) * 0.5, 0.95);
//    }
//    const CGFloat locations[] = {0,progress,endProgress,1.0};
//    //null标识渐变色均匀分布
//    CGGradientRef gradientRef = CGGradientCreateWithColorComponents(colorSpace, components, locations, 4);
    // 释放色彩空间
    CGColorSpaceRelease(colorSpace);
    CGContextReplacePathWithStrokedPath(context);

    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineJoin(context, kCGLineJoinRound);
    CGContextClip(context);
    // 4. 用渐变色填充
    //圆环是逆时针分布，所以上半部分圆环渐变色从-2*radius到28radius
    //下半部分圆环从2*radius到-2radius
    //绘制半圆环
    [self clearDot];
    
    CGPoint startPoint = [self calcCircleCoordinateWithCenter:CGPointMake(radius + width * 0.5, radius + width * 0.5) andWithAngle:beginA andWithRadius:radius];
    CGPoint endPoint = [self calcCircleCoordinateWithCenter:CGPointMake(radius + width * 0.5 , radius + width * 0.5 ) andWithAngle:endA andWithRadius:radius];
    [self addDotViewWithPoint:startPoint];
    [self addDotViewWithPoint:endPoint];
    
//    //如果占了屏幕的一半.则应该是整个视图渐变.暂时设置只展示一段
//    if (endA - beginA >= 150) {
//        CGFloat xOffset = fabs(endPoint.x - startPoint.x);
//        CGFloat yOffset = fabs(endPoint.y - startPoint.y);
//        CGFloat z = sqrt(xOffset * xOffset + yOffset * yOffset);
//        CGFloat newW = 2 * radius * xOffset / z;
//        CGFloat newH = sqrt(radius * radius - (newW * 0.5) * (newW * 0.5));
//
//        if (endPoint.x > startPoint.x && endPoint.y < startPoint.y) {
//            startPoint = CGPointMake(radius - newW * 0.5, radius + newH);
//            endPoint = CGPointMake(radius + newW * 0.5, radius - newH);
//        }else if (endPoint.x > startPoint.x && endPoint.y > startPoint.y) {
//            startPoint = CGPointMake(radius - newW * 0.5, radius - newH);
//            endPoint = CGPointMake(radius + newW * 0.5, radius + newH);
//        }else if (endPoint.x > startPoint.x && endPoint.y > startPoint.y) {
//            endPoint = CGPointMake(radius - newW * 0.5, radius - newH);
//            startPoint = CGPointMake(radius + newW * 0.5, radius + newH);
//        }else {//(endPoint.x < startPoint.x && endPoint.y < startPoint.y)
//            endPoint = CGPointMake(radius - newW * 0.5, radius - newH);
//            startPoint = CGPointMake(radius + newW * 0.5, radius + newH);
//        }
//    }
//    endPoint = [self updatePointValue:endPoint angleValue:endA width:width hasEnd:YES];
//    startPoint = [self updatePointValue:startPoint angleValue:beginA width:width hasEnd:NO];
    
    startPoint = [self calcCircleCoordinateWithCenter:CGPointMake(radius + width * 0.5, radius + width * 0.5) andWithAngle:beginA - 10 andWithRadius:radius];
    endPoint = [self calcCircleCoordinateWithCenter:CGPointMake(radius + width * 0.5, radius + width * 0.5) andWithAngle:endA + 10 andWithRadius:radius];
    [self addRedDotViewWithPoint:endPoint];
    [self addRedDotViewWithPoint:startPoint];
    
//    这个是控制方向的.
    CGContextDrawLinearGradient(context, gradientRef,endPoint, startPoint,0);
    // 释放渐变色
    CGGradientRelease(gradientRef);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    //拉伸当前图像
    CGContextRestoreGState(context);
    UIGraphicsEndImageContext();
    return theImage;
}

////计算的还是有问题.
//-(CGPoint)updatePointValue:(CGPoint)point angleValue:(CGFloat)angle width:(CGFloat)rWidth hasEnd:(BOOL)hasEnd{
//    CGFloat width = rWidth * 2.0;
//    if (hasEnd) {
//        if (angle > 90 && angle <= 270) {
//            point.x -= width;
//            point.y -= width;
//        }else{
//            point.x += width;
//            point.y += width;
//        }
//    }else{
//        if (angle > 90 && angle < 270) {
//            point.x -= width;
//            point.y += width;
//        }else{
//            point.x += width;
//            point.y -= width;
//        }
//    }
//    return point;
//}
    
//获取当前坐标的开始和结束点
-(CGPoint)calcCircleCoordinateWithCenter:(CGPoint) center  andWithAngle : (CGFloat) angle andWithRadius: (CGFloat) radius{
    CGFloat x2 = radius*cosf(angle*M_PI/180);
    CGFloat y2 = radius*sinf(angle*M_PI/180);
    return CGPointMake(center.x+x2, center.y+y2);
}

-(RGBValue *)readRGBForUIColor:(UIColor*)color{
 
    const CGFloat *components = CGColorGetComponents(color.CGColor);
    Byte b = components[2] * 255;
    Byte g = components[1] * 255;
    Byte r = components[0] * 255;
    
    RGBValue *rgb = [[RGBValue alloc]init];
    rgb.b = b;
    rgb.g = g;
    rgb.r = r;
        
    NSLog(@"red:%x\ngreen:%x\nblue:%x",r,g,b);
    return rgb;
}

#pragma mark - 调试渐变的方法

-(NSMutableArray *)dotViews
{
    if (!_dotViews) {
        _dotViews = [NSMutableArray array];
    }
    return _dotViews;
}

-(void)clearDot{
    for (UIView * dotView in self.dotViews) {
        [dotView removeFromSuperview];
    }
    [self.dotViews removeAllObjects];
}

-(void)addDotViewWithPoint:(CGPoint)point{
//    UIView * dotLayer = [[UIView alloc]init];
//    dotLayer.frame = CGRectMake(point.x - 4, point.y - 4, 8, 8);
//    dotLayer.backgroundColor = UIColor.orangeColor;
//    [self.conentImgView addSubview:dotLayer];
//    [self.dotViews addObject:dotLayer];
}

-(void)addRedDotViewWithPoint:(CGPoint)point{
//    UIView * dotLayer = [[UIView alloc]init];
//    dotLayer.frame = CGRectMake(point.x - 4, point.y - 4, 8, 8);
//    dotLayer.backgroundColor = UIColor.redColor;
//    [self.conentImgView addSubview:dotLayer];
//    [self.dotViews addObject:dotLayer];
}

@end
